package com.polytech.diploma.OracleStatStep;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.widgets.Shell;
import org.pentaho.di.core.CheckResult;
import org.pentaho.di.core.CheckResultInterface;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.Counter;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleStepException;
import org.pentaho.di.core.exception.KettleXMLException;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMeta;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.xml.XMLHandler;
import org.pentaho.di.repository.ObjectId;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDataInterface;
import org.pentaho.di.trans.step.StepDialogInterface;
import org.pentaho.di.trans.step.StepIOMeta;
import org.pentaho.di.trans.step.StepIOMetaInterface;
import org.pentaho.di.trans.step.StepInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.StepMetaInterface;
import org.pentaho.di.core.variables.VariableSpace;
import org.pentaho.di.i18n.BaseMessages;

import org.w3c.dom.Node;

public class OracleStatStepMeta extends BaseStepMeta implements StepMetaInterface {
	
	private static Class<?> PKG = OracleStatStepMeta.class; // for i18n purposes, needed by Translator2

	private String stepName;
	private String schemaName;
	private String totalPercent;	
	private String memoryPercent;
	private String ioPercent;
	private String costPercent;
	private String durationPercent;
	private String rowsPercent;
	private String totalPercentage;
	private String totalNumber;
	private String totalDiskSpace;
	
	public OracleStatStepMeta() 
	{
		// allocate BaseStepMeta
		super(); 
	}

	/**
	 * Checks the settings of this step and puts the findings in a remarks List.
	 */
	public void check(List<CheckResultInterface> remarks, TransMeta transMeta, StepMeta stepMeta, 
			RowMetaInterface prev, String input[], String output[], RowMetaInterface info) 
	{
		CheckResult cr;
		if (prev!=null && prev.size()>0)
		{
			cr = new CheckResult(CheckResultInterface.TYPE_RESULT_ERROR, 
					BaseMessages.getString(PKG, "NCPluginMeta.CheckResult.NoInputStreamsError"), 
					stepMeta);
			remarks.add(cr);
		}
		else
		{
			cr = new CheckResult(CheckResultInterface.TYPE_RESULT_OK, 
					BaseMessages.getString(PKG, "NCPluginMeta.CheckResult.NoInputStreamOk"), 
					stepMeta);
			remarks.add(cr);
		}		
	}

	public StepInterface getStep(StepMeta stepMeta, StepDataInterface stepDataInterface, int cnr, TransMeta transMeta, Trans trans)
	{
		return new OracleStatStep(stepMeta, stepDataInterface, cnr, transMeta, trans);
	}

	public StepDataInterface getStepData()
	{
		return new OracleStatStepData();
	}

	public void loadXML(Node stepnode, List<DatabaseMeta> paramList,
			Map<String, Counter> paramMap) throws KettleXMLException {
		readData(stepnode);			
	}

	private void readData(Node stepnode) throws KettleXMLException 
	{
		try
		{
			stepName = XMLHandler.getTagValue(stepnode, "stepName");
			schemaName = XMLHandler.getTagValue(stepnode, "schemaName");
			totalPercent = XMLHandler.getTagValue(stepnode, "totalPercent");
			rowsPercent = XMLHandler.getTagValue(stepnode, "rowsPercent");
			memoryPercent = XMLHandler.getTagValue(stepnode, "memoryPercent");
			ioPercent = XMLHandler.getTagValue(stepnode, "ioPercent");
			costPercent = XMLHandler.getTagValue(stepnode, "costPercent");
			durationPercent = XMLHandler.getTagValue(stepnode, "durationPercent");
			totalPercentage = XMLHandler.getTagValue(stepnode, "totalPercentage");
			totalNumber = XMLHandler.getTagValue(stepnode, "totalNumber");
		}
		catch(Exception e)
		{
			throw new KettleXMLException("Unable to load step info from XML", e);
		}
		
	}

	/**
	 * Read the steps information from a Kettle repository
	 */
	public void readRep(Repository rep, ObjectId id_step, List<DatabaseMeta> databases, Map<String, Counter> counters)
		throws KettleException 
	{
		try
		{
			stepName = rep.getStepAttributeString(id_step, "stepName");
			schemaName = rep.getStepAttributeString(id_step, "schemaName");
			totalPercent = rep.getStepAttributeString(id_step, "totalPercent");
			rowsPercent = rep.getStepAttributeString(id_step, "rowsPercent");
			memoryPercent = rep.getStepAttributeString(id_step, "memoryPercent");
			ioPercent = rep.getStepAttributeString(id_step, "ioPercent");
			costPercent = rep.getStepAttributeString(id_step, "costPercent");
			durationPercent = rep.getStepAttributeString(id_step, "durationPercent");
			totalPercentage = rep.getStepAttributeString(id_step, "totalPercentage");
			totalNumber = rep.getStepAttributeString(id_step, "totalNumber");
		}
		catch(Exception e)
		{
			throw new KettleException("Unexpected error reading step information from the repository", e);
		}	
	}

	/**
	 * Save the steps data into a Kettle repository
	 */
	public void saveRep(Repository rep, ObjectId id_transformation, ObjectId id_step)
			throws KettleException 
	{
		try
		{
			rep.saveStepAttribute(id_transformation, id_step, "stepName", stepName);
			rep.saveStepAttribute(id_transformation, id_step, "schemaName", schemaName);
			rep.saveStepAttribute(id_transformation, id_step, "totalPercent", totalPercent);
			rep.saveStepAttribute(id_transformation, id_step, "rowsPercent", rowsPercent);
			rep.saveStepAttribute(id_transformation, id_step, "memoryPercent", memoryPercent);
			rep.saveStepAttribute(id_transformation, id_step, "ioPercent", ioPercent);
			rep.saveStepAttribute(id_transformation, id_step, "costPercent", costPercent);
			rep.saveStepAttribute(id_transformation, id_step, "durationPercent", durationPercent);
			rep.saveStepAttribute(id_transformation, id_step, "totalPercentage", totalPercentage);
			rep.saveStepAttribute(id_transformation, id_step, "totalNumber", totalNumber);
		}
		catch(Exception e)
		{
			throw new KettleException("Unable to save step information to the repository for id_step="+id_step, e);
		}

	}

	public void setDefault() 
	{
		stepName = "OracleStatStep";
		schemaName = "HR";
		totalPercent = "100";
		memoryPercent = "0";
		ioPercent = "0";
		costPercent = "0";
		durationPercent = "0";
		rowsPercent = "0";
		totalPercentage = "100";
		totalNumber = "0";
		//totalDiskSpace = "0";
	}
	
	public Object clone()
	{
		OracleStatStepMeta retval = (OracleStatStepMeta)super.clone();
		return retval;
	}

	/**
	 * Represents output data format
	 */
	public String getXML() throws KettleException 
	{
		StringBuffer retval = new StringBuffer(300);
				
		retval.append("        ").append(XMLHandler.addTagValue("stepName", stepName));
		retval.append("        ").append(XMLHandler.addTagValue("schemaName", schemaName));
		retval.append("        ").append(XMLHandler.addTagValue("memoryPercent", memoryPercent));
		retval.append("        ").append(XMLHandler.addTagValue("ioPercent", ioPercent));
		retval.append("        ").append(XMLHandler.addTagValue("costPercent", costPercent));
		retval.append("        ").append(XMLHandler.addTagValue("durationPercent", durationPercent));
		retval.append("        ").append(XMLHandler.addTagValue("rowsPercent", rowsPercent));
		retval.append("        ").append(XMLHandler.addTagValue("totalPercentage", totalPercentage));
		retval.append("        ").append(XMLHandler.addTagValue("totalNumber", totalNumber));
		
		return retval.toString();

	}
	
	public void getFields(RowMetaInterface row, String origin, RowMetaInterface[] info, StepMeta nextStep, VariableSpace space) throws KettleStepException
	{
		row.clear();
		
		List<CheckResultInterface> remarks = new ArrayList<CheckResultInterface>();
		
		ValueMetaInterface sqlText = new ValueMeta("SqlText", ValueMetaInterface.TYPE_STRING);
		sqlText.setOrigin(origin);
		row.addValueMeta(sqlText);
		
		ValueMetaInterface runtimeMemory = new ValueMeta("RuntimeMemory", ValueMetaInterface.TYPE_STRING);
		runtimeMemory.setOrigin(origin);
		row.addValueMeta(runtimeMemory);
			
		ValueMetaInterface persistentMemory = new ValueMeta("PersistentMemory", ValueMetaInterface.TYPE_STRING);
		persistentMemory.setOrigin(origin);
		row.addValueMeta(persistentMemory);	

		ValueMetaInterface diskReads = new ValueMeta("DiskReads", ValueMetaInterface.TYPE_STRING);
		diskReads.setOrigin(origin);
		row.addValueMeta(diskReads);
		
		ValueMetaInterface bufferGets = new ValueMeta("BufferGets", ValueMetaInterface.TYPE_STRING);
		bufferGets.setOrigin(origin);
		row.addValueMeta(bufferGets);
		
		ValueMetaInterface userIOWaitTime = new ValueMeta("UserIOWaitTime", ValueMetaInterface.TYPE_STRING);
		userIOWaitTime.setOrigin(origin);
		row.addValueMeta(userIOWaitTime);
		
		ValueMetaInterface rowsProcessed = new ValueMeta("RowsProcessed", ValueMetaInterface.TYPE_STRING);
		rowsProcessed.setOrigin(origin);
		row.addValueMeta(rowsProcessed);
		
		ValueMetaInterface optimizerCost = new ValueMeta("OptimizerCost", ValueMetaInterface.TYPE_STRING);
		optimizerCost.setOrigin(origin);
		row.addValueMeta(optimizerCost);
		
		ValueMetaInterface elapsedTime = new ValueMeta("ElapsedTime", ValueMetaInterface.TYPE_STRING);
		elapsedTime.setOrigin(origin);
		row.addValueMeta(elapsedTime);
		
		ValueMetaInterface firstLoadTime = new ValueMeta("FirstLoadTime", ValueMetaInterface.TYPE_DATE);
		firstLoadTime.setOrigin(origin);
		row.addValueMeta(firstLoadTime);
		
		ValueMetaInterface commandType = new ValueMeta("CommandType", ValueMetaInterface.TYPE_STRING);
		commandType.setOrigin(origin);
		row.addValueMeta(commandType);
		
		ValueMetaInterface replaceList = new ValueMeta("ReplaceList", ValueMetaInterface.TYPE_STRING);
		replaceList.setOrigin(origin);
		row.addValueMeta(replaceList);
		
		if (!remarks.isEmpty()) {
			StringBuffer stringRemarks = new StringBuffer();
			for (CheckResultInterface remark : remarks) {
				stringRemarks.append(remark.toString()).append(Const.CR);
			}
			throw new KettleStepException(stringRemarks.toString());
		}
	}

	/**
     * Returns the Input/Output metadata for this step.
     * The step only produces output, does not accept input!
     */
    public StepIOMetaInterface getStepIOMeta() {
    	return new StepIOMeta(true, true, false, false, false, false);
    }
    
	public StepDialogInterface getDialog(Shell shell, StepMetaInterface meta, TransMeta transMeta, String name) {
        return new OracleStatStepDialog(shell, meta, transMeta, name);
    }

	public String getStepName() {
		return stepName;
	}

	public void setStepName(String stepName) {
		this.stepName = stepName;
	}

	public String getSchemaName() {
		return schemaName;
	}

	public void setSchemaName(String schemaName) {
		this.schemaName = schemaName;
	}

	public String getTotalPercent() {
		return totalPercent;
	}

	public void setTotalPercent(String totalPercent) {
		this.totalPercent = totalPercent;
	}

	public String getMemoryPercent() {
		return memoryPercent;
	}

	public void setMemoryPercent(String memoryPercent) {
		this.memoryPercent = memoryPercent;
	}

	public String getIoPercent() {
		return ioPercent;
	}

	public void setIoPercent(String ioPercent) {
		this.ioPercent = ioPercent;
	}

	public String getCostPercent() {
		return costPercent;
	}

	public void setCostPercent(String costPercent) {
		this.costPercent = costPercent;
	}

	public String getDurationPercent() {
		return durationPercent;
	}

	public void setDurationPercent(String durationPercent) {
		this.durationPercent = durationPercent;
	}

	public String getRowsPercent() {
		return rowsPercent;
	}

	public void setRowsPercent(String rowsPercent) {
		this.rowsPercent = rowsPercent;
	}

	public String getTotalDiskSpace() {
		return totalDiskSpace;
	}

	public String getTotalNumber() {
		return totalNumber;
	}

	public String getTotalPercentage() {
		return totalPercentage;
	}

	public void setTotalDiskSpace(String totalDiskSpace) {
		this.totalDiskSpace = totalDiskSpace;
	}

	public void setTotalNumber(String totalNumber) {
		this.totalNumber = totalNumber;
	}

	public void setTotalPercentage(String totalPercentage) {
		this.totalPercentage = totalPercentage;
	}
	
}
